package com.bangcommunity.bbframe.sdm.web.shiro.filter;

import com.bangcommunity.bbframe.common.base.BaseResult;
import com.bangcommunity.bbframe.common.base.MainConfigLoader;
import com.bangcommunity.bbframe.common.utils.lang.StringUtils;
import com.bangcommunity.bbframe.sdm.utils.JacksonUtil;
import com.bangcommunity.bbframe.sdm.utils.RequestUtils;
import com.bangcommunity.bbframe.sdm.utils.ShiroUtils;
import com.bangcommunity.bbframe.sdm.web.exception.RestConf;
import com.bangcommunity.bbframe.sdm.web.shiro.ISdmWebTokenService;
import com.bangcommunity.bbframe.sdm.web.shiro.realm.IShiroUser;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.AuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * 基于Shiro 实现的SSO登陆认证的Filter
 *
 * @version 1.0
 * @author tanghc
 */
public class BaseSdmLogoutFilter extends AuthenticationFilter {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired(required = false)
    private ISdmWebTokenService sdmWebTokenService;

    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        removeToken();
        try {
            Subject subject = getSubject(request, response);
            subject.logout();
            boolean ajaxRequest = RequestUtils.isAjaxRequest((HttpServletRequest) request);
            if (ajaxRequest || RestConf.isRest) {
                BaseResult result = BaseResult.success("logout success");
                HttpServletResponse res = (HttpServletResponse) response;
                res.setHeader("Content-Type", "application/json;charset=utf-8");
                PrintWriter out = res.getWriter();
                JacksonUtil jsonMapper = new JacksonUtil();
                out.write(jsonMapper.toJson(result));
                out.flush();
                out.close();
            } else {
                String redirectUrl = getLoginUrl();
                String url = request.getParameter("url");
                if (StringUtils.isNotBlank(url)) {
                    redirectUrl = url;
                }
                String productCode = request.getParameter("productCode");
                String appCode = request.getParameter("appCode");
                if (StringUtils.isBlank(productCode)) {
                    productCode = MainConfigLoader.getInstance().getProductCode();
                }
                if (StringUtils.isBlank(appCode)) {
                    appCode = MainConfigLoader.getInstance().getAppCode();
                }
                if (redirectUrl.indexOf("?") != -1) {
                    redirectUrl += "&";
                } else {
                    redirectUrl += "?";
                }
                redirectUrl += "productCode=" + productCode + "&appCode=" + appCode;
                WebUtils.issueRedirect(request, response, redirectUrl);
            }
        } catch (Exception e) {
            logger.error("onLoginFailure response exceptioon: ", e);
        }
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        return false;
    }

    protected void removeToken() {
        try {
            IShiroUser currentUser = ShiroUtils.getCurrentUser();
            if (null != currentUser && StringUtils.isNotBlank(currentUser.getToken())) {
                sdmWebTokenService.removeToken(currentUser.getToken());
            }
        } catch (Exception e) {
            logger.error("remove sso token exception", e);
        }
    }
}
